﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Text;
using System.IO;

namespace VidoopSecure
{
    /// <summary>
    /// A proxy class for making web service calls to the VidoopSecure service.
    /// </summary>
    /// <remarks>This class is intended to be used by the 
    /// <see cref="VidoopSecure.VSManager" /> singleton object and the
    /// <see cref="VidoopSecure.Service" />-derived class objects.</remarks>
    public class HttpProxy
    {
        public HttpWebRequest Request
        {
            get { return _request; }
            set { _request = value; }
        }

        public HttpWebResponse Response
        {
            get { return _response; }
        }

        /// <summary>
        /// Http Status Code.
        /// </summary>
        public int StatusCode
        {
            get
            {
                if (_response != null)
                {
                    // HttpStatusCodes values == their HTTP code
                    return (int)_response.StatusCode;
                }
                else if (_webException != null)
                {
                    return Util.GetHttpStatus(_webException);
                }
                else
                    return -1;
            }
        }



        /// <summary>
        /// Make an API call to the VidoopSecure web service.
        /// </summary>
        /// <param name="url">Absolute URL for the API endpoint.</param>
        /// <param name="method">HTTP method ("GET" or "POST")</param>
        /// <param name="parameters"><see cref="System.Collections.Generic.Dictionary" />
        /// containing parameters to the API call.</param>
        /// <param name="credentials">API user credentials where containing username
        /// and password separated by a color (':').</param>
        /// <returns><see cref="System.Net.HttpWebResponse" /> object.</returns>
        /// <exception cref="VidoopSecureException">Thrown in the event of an
        /// unexpected failure.</exception>
        /// <seealso cref="VidoopSecure" />
        public void ApiCall(string url, string method, Dictionary<string, string> parameters,  string credentials) 
        {
//            this.Request = (HttpWebRequest)WebRequest.Create(url);

            CredentialCache credCache = null;

            if (!string.IsNullOrEmpty(credentials))
            {
                string username, password;
                Util.ParseCredentials(credentials, out username, out password);

                 credCache = new CredentialCache();
                 credCache.Add(new Uri(url), "Basic", new NetworkCredential(username, password));
            }

            method = method.ToUpper();

            if (method == "POST")
            {
                this.Request = (HttpWebRequest)WebRequest.Create(url);

                this.Request.Method = method;
                this.Request.ContentType = "application/x-www-form-urlencoded";

                if (credCache != null)
                    this.Request.Credentials = credCache;
                
                if (parameters != null && parameters.Count > 0)
                {
                    string paramStr = Util.CreatePostParamsString(parameters);
                    byte[] buffer = Encoding.UTF8.GetBytes(paramStr);

                    this.Request.ContentLength = buffer.Length;

                    Stream data = this.Request.GetRequestStream();

                    data.Write(buffer, 0, buffer.Length);
                    data.Close();
                }
            }
            else if (method == "GET")
            {

                if (parameters != null && parameters.Count > 0)
                {
                    url += "?" + Util.CreateQueryParamsString(parameters);
                }
                
                this.Request = (HttpWebRequest)WebRequest.Create(url);

                this.Request.Method = method;
 
                if (credCache != null)
                    this.Request.Credentials = credCache;
            }

            // This is necessary because GetResponse throws a WebException
            // if the remote server returns certain failure status codes.
            try
            {
                this._response = (HttpWebResponse)this.Request.GetResponse();
            }
            catch (WebException e)
            {
                this._webException = e;
            }
        }

        /// <summary>
        /// Closes this object to any further action.
        /// </summary>
        public void Close()
        {
            if (this._response != null)
                this._response.Close();
        }

        private HttpWebRequest _request;
        private HttpWebResponse _response;
        private WebException _webException;
    }
}
